﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Xml.Serialization;

namespace FlickrSL.Data
{
    [XmlType("photoset")]
    public class Photoset : List<PhotosetPhoto>
    {
        [XmlAttribute("id")]
        public Int64 Id { get; set; }

        [XmlAttribute("primary")]
        public Int64 PrimaryPhotoId { get; set; }

        [XmlAttribute("owner")]
        public String OwnerId { get; set; }

        [XmlAttribute("ownername")]
        public String OwnerName { get; set; }

        [XmlAttribute("page")]
        public Int32 Page { get; set; }

        [XmlAttribute("perpage")]
        public Int32 PerPage { get; set; }

        [XmlAttribute("pages")]
        public Int32 PageCount { get; set; }

        [XmlAttribute("total")]
        public Int32 Total { get; set; }

        public Photoset()
        {
        }

        public Photoset(Int32 capacity)
            : base(capacity)
        {
        }

        public Photoset(IEnumerable<PhotosetPhoto> photos)
            : base(photos)
        {
        }
    }

    [XmlType("photo")]
    public class PhotosetPhoto
    {
        [XmlAttribute("isprimary")]
        public Boolean IsPrimary { get; set; }
        [XmlAttribute("id")]
        public Int64 Id { get; set; }

        [XmlAttribute("owner")]
        public String OwnerId { get; set; }

        [XmlAttribute("ownername")]
        public String OwnerName { get; set; }

        [XmlAttribute("title")]
        public String Title { get; set; }

        [XmlElement("description", IsNullable = true)]
        public String Description { get; set; }

        [XmlAttribute("tags")]
        public String[] Tags { get; set; }

        [XmlAttribute("machine_tags")]
        public String[] MachineTags { get; set; }

        [XmlAttribute("o_width")]
        public Int32 WidthOfOriginal { get; set; }

        [XmlAttribute("o_height")]
        public Int32 HeightOfOriginal { get; set; }

        [XmlAttribute("secret")]
        public String Secret { get; set; }

        [XmlAttribute("originalsecret")]
        public String OriginalSecret { get; set; }

        [XmlAttribute("originalformat")]
        public String OriginalFormat { get; set; }

        [XmlAttribute("ispublic")]
        public Boolean IsPublic { get; set; }

        [XmlAttribute("isfriend")]
        public Boolean IsFriend { get; set; }

        [XmlAttribute("license")]
        public Int32 LicenseId { get; set; }

        [XmlIgnore]
        public DateTime? DatePosted { get; set; }

        [XmlAttribute("dateupload")]
        public String DatePostedString
        {
            get
            {
                if (this.DatePosted.HasValue)
                {
                    return ((Int64)this.DatePosted.Value.ToUniversalTime().Subtract(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds).ToString();
                }
                else
                {
                    return null;
                }
            }

            set
            {
                if (!String.IsNullOrEmpty(value))
                {
                    this.DatePosted = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(Int64.Parse(value));
                }
                else
                {
                    this.DatePosted = null;
                }
            }
        }

        [XmlIgnore]
        public DateTime? DateTaken { get; set; }

        [XmlAttribute("datetaken")]
        public String DateTakenString
        {
            get
            {
                if (this.DateTaken.HasValue)
                {
                    return this.DateTaken.Value.ToString("yyyy-MM-dd HH:mm:ss");
                }
                else
                {
                    return null;
                }
            }

            set
            {
                if (!String.IsNullOrEmpty(value))
                {
                    this.DateTaken = DateTime.ParseExact(value, "yyyy-MM-dd HH:mm:ss", CultureInfo.CurrentCulture);
                }
                else
                {
                    this.DateTaken = null;
                }
            }
        }

        [XmlIgnore]
        public DateGranularity DateTakenGranularity { get; set; }

        [XmlAttribute("datetakengranularity")]
        public Int32 DateTakenGranularityValue
        {
            get { return (Int32)this.DateTakenGranularity; }
            set { this.DateTakenGranularity = (DateGranularity)value; }
        }

        [XmlIgnore]
        public DateTime? LastUpdate { get; set; }

        [XmlAttribute("lastupdate")]
        public String LastUpdateString
        {
            get
            {
                if (this.LastUpdate.HasValue)
                {
                    return ((Int64)this.LastUpdate.Value.ToUniversalTime().Subtract(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds).ToString();
                }
                else
                {
                    return null;
                }
            }

            set
            {
                if (!String.IsNullOrEmpty(value))
                {
                    this.LastUpdate = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(Int64.Parse(value));
                }
                else
                {
                    this.LastUpdate = null;
                }
            }
        }

        [XmlAttribute("media")]
        public String MediaTypeString
        {
            get { return this.MediaType.ToString().ToLower(); }
            set { this.MediaType = (MediaType)Enum.Parse(typeof(MediaType), value, true); }
        }

        [XmlIgnore]
        public MediaType MediaType { get; set; }

        [XmlAttribute("media_status")]
        public String MediaStatus { get; set; }

        [XmlAttribute("latitude")]
        public Double Latitude { get; set; }

        [XmlAttribute("longitude")]
        public Double Longitude { get; set; }

        [XmlIgnore]
        public LocationAccuracy Accuracy { get; set; }

        [XmlAttribute("accuracy")]
        public Int32 AccuracyValue
        {
            get { return (Int32)this.Accuracy; }
            set { this.Accuracy = (LocationAccuracy)value; }
        }

        [XmlAttribute("server")]
        public Int32 Server { get; set; }

        [XmlAttribute("farm")]
        public Int32 ServerFarm { get; set; }

        [XmlAttribute("iconserver")]
        public Int32 IconServer { get; set; }

        [XmlAttribute("iconfarm")]
        public Int32 IconServerFarm { get; set; }

        [XmlAttribute("pathalias")]
        public String PathAlias { get; set; }

        [XmlAttribute("views")]
        public Int32 ViewCount { get; set; }

        [XmlAttribute("url_o")]
        public String OriginalUrl { get; set; }

        [XmlAttribute("width_o")]
        public Int32 OriginalWidth { get; set; }

        [XmlAttribute("height_o")]
        public Int32 OriginalHeight { get; set; }

        [XmlAttribute("url_sq")]
        public String SquareUrl { get; set; }

        [XmlAttribute("width_sq")]
        public Int32 SquareWidth { get; set; }

        [XmlAttribute("height_sq")]
        public Int32 SquareHeight { get; set; }

        [XmlAttribute("url_t")]
        public String TinyUrl { get; set; }

        [XmlAttribute("width_t")]
        public Int32 TinyWidth { get; set; }

        [XmlAttribute("height_t")]
        public Int32 TinyHeight { get; set; }

        [XmlAttribute("url_s")]
        public String SmallUrl { get; set; }

        [XmlAttribute("width_s")]
        public Int32 SmallWidth { get; set; }

        [XmlAttribute("height_s")]
        public Int32 SmallHeight { get; set; }

        [XmlAttribute("url_m")]
        public String MediumUrl { get; set; }

        [XmlAttribute("width_m")]
        public Int32 MediumWidth { get; set; }

        [XmlAttribute("height_m")]
        public Int32 MediumHeight { get; set; }
    }
}
